﻿namespace SharpF2.ModelView
{
	using System;
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Text.RegularExpressions;

	/// <summary>
	/// Define a text resource; text, Identifiers...
	/// </summary>
	public class Item : INotifyPropertyChanged
	{
		#region Events

		/// <summary>
		/// Event raised when a property has changed.
		/// </summary>
		public event PropertyChangedEventHandler PropertyChanged;

		#endregion

		#region Protected Attributes

		/// <summary>
		/// The error message if and identifier identification has failed.
		/// </summary>
		protected string errorMessage;

		#endregion

		#region Private Attributes

		/// <summary>
		/// Collection of IdentifierId associated with the corresonding 
		/// information in the input file name.
		/// </summary>
		private Dictionary<string, string> identifiersValue = new Dictionary<string, string>();

		#endregion

		#region Public Properties

		/// <summary>
		/// Gets or sets ErrorMessage.
		/// </summary>
		public string ErrorMessage
		{
			get { return errorMessage; }

			set
			{
				errorMessage = value;
				NotifyPropertyChanged("ErrorMessage");
			}
		}

		/// <summary>
		/// Gets or sets IdentifiersValue.
		/// </summary>
		public Dictionary<string, string> IdentifiersValue
		{
			get { return identifiersValue; }

			set
			{
				identifiersValue = value;
				NotifyPropertyChanged("IdentifiersValue");
			}
		}

		#endregion

		#region Protected Properties

		/// <summary>
		/// Gets or sets the text which contain the identifier data.
		/// </summary>
		protected string RegexText { get; set; }

		#endregion

		#region Public Members

		/// <summary>
		/// Update the IdentifiersValue from a new dictionary of identifiers.
		/// </summary>
		/// <param name="regex">The regular expression to extract identifiers.</param>
		/// <param name="identifiers">The new dictionary of identifiers.</param>
		/// <returns>
		/// True if there was an error while the regex matching, else false.
		/// </returns>
		public bool UpdateIdentifiers(Regex regex, IEnumerable<IdentifierItem> identifiers)
		{
			if (null == regex || null == identifiers)
				return true;

			var failToMatch = false;
			IdentifiersValue.Clear();

			try
			{
				var match = regex.Match(RegexText);
				if (match.Success)
				{
					foreach (var identifier in identifiers)
					{
						var token = match.Result("${" + identifier.IdentifierId + "}");
						token = identifier.Filter(token);
						if (!token.StartsWith("${"))
							IdentifiersValue[identifier.IdentifierId] = token;
					}
				}
				else
					failToMatch = true;
			}
			catch (ArgumentNullException e)
			{
				ErrorMessage = e.Message;
				failToMatch = true;
			}

			NotifyPropertyChanged("IdentifiersValue");
			return failToMatch;
		}

		#endregion

		#region Protected Members

		/// <summary>
		/// Raise a PropertyChanged event.
		/// </summary>
		/// <param name="info">Property changed event args.</param>
		protected void NotifyPropertyChanged(string info)
		{
			if (PropertyChanged != null)
			{
				PropertyChanged(this, new PropertyChangedEventArgs(info));
			}
		}

		#endregion
	}
}